#include "mvc/model/aircrafts/conventional/conventional_wings.h"
#include "mvc/model/aircrafts/aircraft_rcurves.h"
#include "mvc/model/aircrafts/aircraft_parameters.h"
#include "common/log/QsLog.h"

/**
  * The Conventional wings constructor.
  * id -  the configuration id.
  * parameters - the all parameters of the conventional wings configuration.
  * airfoils - the airfoils of the conventional wings configuration.
  */
Conventional_Wings::Conventional_Wings(int id, Parameters *parameters, Airfoils_curve_map *airfoils)
    : Aircraft(id, parameters, airfoils)
{
    _geometries.resize(4);

    is_refcur_map_generated = is_refcurves_generated = false;
}

/**
  * Draws the enterely geometry using or not texture.
  * texture - Specified if the geometry will be drawn with texture
  */
void Conventional_Wings::draw(bool texture) const
{
//    QLOG_INFO() << "Conventional::draw" << endl;

//    generate_geometry();

    int knpc = (*_parameters)[s_wings][wings_npc] + 1;
    int knpf = (*_parameters)[s_fuselage][fuselage_npf] + 1;
    int knpcht = (*_parameters)[s_horizontal_tail][htail_npc] + 1;

    draw_geometry(p_ls, knpc, texture);
    draw_geometry(p_fuselage, knpf, texture);
    draw_geometry(p_vtail, knpcht, texture);
    draw_geometry(p_htail, knpcht, texture);
}

/**
  * Generate the enterely geometry, and the reference curves if it is necesary
  */
void Conventional_Wings::generate_geometry()
{
//    QLOG_INFO() << "Conventional::generate_geometry";
    if(not is_refcur_map_generated)
        generate_reference_curves_index();

    if(not is_refcurves_generated)
        generate_reference_curves();

    if(not is_configuration_generated)
    {
        _geometries[p_ls] = create_wings();
        _geometries[p_htail] = create_horizontal_tail();
        _geometries[p_fuselage] = create_fuselage();
        _geometries[p_vtail] = create_vertical_tail();

        is_configuration_generated = true;
    }
}

//
// PROTECTED METHODS
//

/**
  * Redefine the method to generate the wings reference curves index
  * c_index - the current index of a free space on the vector of geometries.
  * returns the next index of a free space on the vector of geometries.
  */
int Conventional_Wings::generate_rc_wings_index(int c_index)
{
//    cout << "Uav_joined_wings::generate_rc_wings_index" << endl;
    c_index = Aircraft::generate_rc_wings_index(c_index);

    reference_curves_map.insert(irc_externw, reference_curves_map[frc_wings]);
    reference_curves_map.insert(frc_externw, c_index++);

    return c_index;
}

/**
  * Generate the reference curves, used to create the geometry.
  */
void Conventional_Wings::generate_reference_curves()
{
    QLOG_INFO() << "Conventional::generate_reference_curves";
    int knpc = ((*_parameters)[s_wings])[wings_npc] + 1;
    int knpcht = (*_parameters)[s_horizontal_tail][htail_npc] + 1;

    generate_wings_refcurves();
    generate_fuselage_refcurves(knpc);
    generate_horizontal_tail_refcurves();
    generate_vertical_tail_refcurves(knpcht);

    is_refcurves_generated = true;
}

/**
  * Generate the reference curves of the horizontal tail
  */
void Conventional_Wings::generate_horizontal_tail_refcurves()
{
    QLOG_INFO() << "Conventional::generate_horizontal_tail_refcurves";
    QMap<QString, float> &htail_params = (*_parameters)[s_horizontal_tail];
    QMap<QString, float> &vtail_params = (*_parameters)[s_vertical_tail];

    int knpc = htail_params[htail_npc] + 1;

    double x = htail_params[htail_xfa];
    double z = vtail_params[vtail_zfa];
    Point3D _locatep(-x, 0.0, -z);

    create_wcurve(reference_curves_map[irc_horizontal_tail], knpc, htail_root, 0.0,
                  htail_params[htail_cra], htail_params[htail_ara], 0.0, 0.0, &_locatep);
    create_wcurve(reference_curves_map[frc_horizontal_tail], knpc, htail_wingtip,
                  htail_params[htail_sib], htail_params[htail_cz], htail_params[htail_arf],
                  htail_params[htail_dib], htail_params[htail_lib], &_locatep);
}
